#include "SGPCLJsonConfig.h"

namespace sgpcl
{

std::unique_ptr<SGVisualConfig> SGVisualConfig::spDefaultValue = nullptr;

SGVisualConfig::SGVisualConfig()
  : bPlot(false)      // 是否进行可视化
  , bSaveAsPLY(false) // 是否保存为PLY
  , strPLYFileName("output.ply") // 保存的PLY文件名
  , bSaveAsPNG(false) // 是否保存为PNG
  , strPNGFileName("output.png") // 保存的PNG文件名
  , bSaveAsGIF(false) // 是否保存为GIF
  , strGIFFileName("output.gif") // 保存的GIF文件名
  , fPointSize(2.f)   // 点大小
  , fVecSize(1.f)     // 矢量大小
  , nVecLevel(10)     // 法矢密度
  , fAxisSize(0.f)    // 坐标系尺寸
  , strTitle("Cloud") // 可视化窗口名称
  , r(0.f)
  , g(0.f)
  , b(0.f)
  , a(0.f)
  , pos_x(0.f)
  , pos_y(-20.f)
  , pos_z(0.f)
  , view_x(0.f)
  , view_y(1.f)
  , view_z(0.f)
  , view_up_x(0.f)
  , view_up_y(0.f)
  , view_up_z(1.f)
{
}

/// <summary>
/// 从Json文件解析参数
/// </summary>
/// <param name="cConfigFileName">文件路径</param>
void SGVisualConfig::ParseJson(const rapidjson::Value& sJsonRoot)
{
  // 如果可视化参数提供了默认值，先赋值为默认值
  SGVisualConfig* sDefaultConfig = SGVisualConfig::GetDefaultValue();
  if (sDefaultConfig)
  {
    *this = *sDefaultConfig;
  }
  // 是否可视化
  rapidjson::Value::ConstMemberIterator itMember = sJsonRoot.FindMember("Plot");
  if (itMember != sJsonRoot.MemberEnd())
  {
    bPlot = itMember->value.GetBool();
  }

  // 是否保存为PLY
  itMember = sJsonRoot.FindMember("SaveAsPLY");
  if (itMember != sJsonRoot.MemberEnd())
  {
    bSaveAsPLY = itMember->value.GetBool();
  }
  if (bSaveAsPLY)
  {
    itMember = sJsonRoot.FindMember("PLYFileName");
    if (itMember != sJsonRoot.MemberEnd())
    {
      strPLYFileName = itMember->value.GetString();
    }
  }

  // 是否保存为PNG
  itMember = sJsonRoot.FindMember("SaveAsPNG");
  if (itMember != sJsonRoot.MemberEnd())
  {
    bSaveAsPNG = itMember->value.GetBool();
  }
  if (bSaveAsPNG)
  {
    itMember = sJsonRoot.FindMember("PNGFileName");
    if (itMember != sJsonRoot.MemberEnd())
    {
      strPNGFileName = itMember->value.GetString();
    }
  }

  // 是否保存为GIF
  itMember = sJsonRoot.FindMember("SaveAsGIF");
  if (itMember != sJsonRoot.MemberEnd())
  {
    bSaveAsGIF = itMember->value.GetBool();
  }
  if (bSaveAsGIF)
  {
    itMember = sJsonRoot.FindMember("GIFFileName");
    if (itMember != sJsonRoot.MemberEnd())
    {
      strGIFFileName = itMember->value.GetString();
    }
  }

  // 点大小
  itMember = sJsonRoot.FindMember("PointSize");
  if (itMember != sJsonRoot.MemberEnd())
  {
    fPointSize = itMember->value.GetFloat();
  }

  // 法矢长度
  itMember = sJsonRoot.FindMember("VecSize");
  if (itMember != sJsonRoot.MemberEnd())
  {
    fVecSize = itMember->value.GetFloat();
  }

  // 法矢密度
  itMember = sJsonRoot.FindMember("VecLevel");
  if (itMember != sJsonRoot.MemberEnd())
  {
    nVecLevel = itMember->value.GetInt();
  }

  // 坐标轴大小
  itMember = sJsonRoot.FindMember("AxisSize");
  if (itMember != sJsonRoot.MemberEnd())
  {
    fAxisSize = itMember->value.GetFloat();
  }

  // 标题
  itMember = sJsonRoot.FindMember("Title");
  if (itMember != sJsonRoot.MemberEnd())
  {
    strTitle = itMember->value.GetString();
  }

  // 背景色
  itMember = sJsonRoot.FindMember("BackGround");
  if (itMember != sJsonRoot.MemberEnd())
  {
    rapidjson::Value::ConstMemberIterator itSubMember = itMember->value.FindMember("r");
    if (itSubMember != itMember->value.MemberEnd())
    {
      r = itSubMember->value.GetFloat();
    }
    itSubMember = itMember->value.FindMember("g");
    if (itSubMember != itMember->value.MemberEnd())
    {
      g = itSubMember->value.GetFloat();
    }
    itSubMember = itMember->value.FindMember("b");
    if (itSubMember != itMember->value.MemberEnd())
    {
      b = itSubMember->value.GetFloat();
    }
  }

  // 视点坐标
  itMember = sJsonRoot.FindMember("ViewCoord");
  if (itMember != sJsonRoot.MemberEnd())
  {
    rapidjson::Value::ConstMemberIterator itSubMember = itMember->value.FindMember("x");
    if (itSubMember != itMember->value.MemberEnd())
    {
      pos_x = itSubMember->value.GetFloat();
    }
    itSubMember = itMember->value.FindMember("y");
    if (itSubMember != itMember->value.MemberEnd())
    {
      pos_y = itSubMember->value.GetFloat();
    }
    itSubMember = itMember->value.FindMember("z");
    if (itSubMember != itMember->value.MemberEnd())
    {
      pos_z = itSubMember->value.GetFloat();
    }
  }

  // 视点方向
  itMember = sJsonRoot.FindMember("ViewDirection");
  if (itMember != sJsonRoot.MemberEnd())
  {
    rapidjson::Value::ConstMemberIterator itSubMember = itMember->value.FindMember("x");
    if (itSubMember != itMember->value.MemberEnd())
    {
      view_x = itSubMember->value.GetFloat();
    }
    itSubMember = itMember->value.FindMember("y");
    if (itSubMember != itMember->value.MemberEnd())
    {
      view_y = itSubMember->value.GetFloat();
    }
    itSubMember = itMember->value.FindMember("z");
    if (itSubMember != itMember->value.MemberEnd())
    {
      view_z = itSubMember->value.GetFloat();
    }
  }

  // 视点上方向
  itMember = sJsonRoot.FindMember("UpperDirection");
  if (itMember != sJsonRoot.MemberEnd())
  {
    rapidjson::Value::ConstMemberIterator itSubMember = itMember->value.FindMember("x");
    if (itSubMember != itMember->value.MemberEnd())
    {
      view_up_x = itSubMember->value.GetFloat();
    }
    itSubMember = itMember->value.FindMember("y");
    if (itSubMember != itMember->value.MemberEnd())
    {
      view_up_y = itSubMember->value.GetFloat();
    }
    itSubMember = itMember->value.FindMember("z");
    if (itSubMember != itMember->value.MemberEnd())
    {
      view_up_z = itSubMember->value.GetFloat();
    }
  }
}

void SGVisualConfig::SetDefaultValue(const rapidjson::Value& sJsonRoot)
{
  if (!spDefaultValue)
  {
    spDefaultValue = std::make_unique<SGVisualConfig>();
    spDefaultValue->ParseJson(sJsonRoot);
  }
}

SGVisualConfig* SGVisualConfig::GetDefaultValue()
{
  return spDefaultValue.get();
}

SGPCLJsonConfig::SGPCLJsonConfig()
  : bPerform(true)
  , bInPlace(true)
  , sVisConfig()
{
}

// 是否执行该操作
bool SGPCLJsonConfig::IfPerform() const
{
  return bPerform;
}
// 该操作后是否覆盖原点云
bool SGPCLJsonConfig::IfInPlace() const
{
  return bInPlace;
}
// 是否需要绘图窗口
bool SGPCLJsonConfig::IfNeedPlotWindow() const {
  return IfVis() || IfSaveAsPNG() || IfSaveAsGIF();
}
  // 该操作后是否进行可视化
bool SGPCLJsonConfig::IfVis() const
{
  return sVisConfig.bPlot;
}

// 该操作后是否保存为PNG
bool SGPCLJsonConfig::IfSaveAsPNG() const
{
  return sVisConfig.bSaveAsPNG;
}

// 该操作后是否保存为GIF
bool SGPCLJsonConfig::IfSaveAsGIF() const
{
  return sVisConfig.bSaveAsGIF;
}

/// <summary>
/// 从Json文件解析参数
/// </summary>
/// <param name="cConfigFileName">文件路径</param>
void SGPCLJsonConfig::ParseJson(
  const rapidjson::Value& sJsonRoot, const std::string& strOperatorName)
{
  // 是否进行该操作
  rapidjson::Value::ConstMemberIterator itMember = sJsonRoot.FindMember("Perform");
  if (itMember != sJsonRoot.MemberEnd())
  {
    bPerform = itMember->value.GetBool();
  }
  if (!bPerform)
  {
    SG_LOG("提示：不进行" + strOperatorName + "操作！");
  }

  // 该操作后是否覆盖原点云
  itMember = sJsonRoot.FindMember("InPlace");
  if (itMember != sJsonRoot.MemberEnd())
  {
    bInPlace = itMember->value.GetBool();
  }
  if (!bInPlace)
  {
    SG_LOG("提示：" + strOperatorName + "操作后不覆盖原点云！");
  }

  // 可视化参数（不提供用默认值，也不警告）
  itMember = sJsonRoot.FindMember("Vis");
  if (itMember != sJsonRoot.MemberEnd())
  {
    sVisConfig.ParseJson(itMember->value);
  }
}


/// <summary>
/// 从字符串解析参数
/// </summary>
/// <param name="strJson"></param>
void SGPCLJsonConfig::ParseJson(const std::string& strJson)
{
  // 将字符串转为rapidjson节点数据
  rapidjson::Document sDoc;
  if (sDoc.Parse(strJson.c_str()).HasParseError())
  {
    SG_PANIC("解析JSON格式的参数文件出错！");
  }
  rapidjson::Value& sJsonRoot = sDoc;

  // 解析参数
  ParseJson(sJsonRoot);

  return;
}

} // namespace sgpcl
